//
// Created by hamlet on 23-4-9.
//

#ifndef COMPILERS_LEX_H
#define COMPILERS_LEX_H

#include <exception>
#include <istream>
#include <string>
#include <unordered_map>
#include <vector>
#include "Token.h"

// 词法分析器
class Lex {
public:
    std::shared_ptr<Token> getToken(std::istream &in);

    void init();

    [[maybe_unused]] bool analyze(std::istream &in, std::vector<Token> &result);

    [[maybe_unused]] void output(const std::vector<Token> &result) const;

    std::string getPos() const;

    void resetPos() { position = {1, 1}; }

    std::vector<std::string> idList;  // 标识符表
    std::vector<int> valueIntList;  // 整形常数表

private:
    static const std::unordered_map<std::string, TokenType> reservedWordMap;  // 保留字表

    std::unordered_map<std::string, int> idMap;  // 标识符索引表

    std::pair<int, int> position{1, 1};  // 当前读取到的代码位置
    int pastPosY;

public:
    class ExcEOF : public std::exception {
    };

    class ExcLex : public std::exception {
    };

    class ExcUnknownChar : public ExcLex {
        std::string desc_;

        [[nodiscard]] const char *what() const noexcept override;

    public:
        explicit ExcUnknownChar(char c);
    };
};


#endif //COMPILERS_LEX_H
